package com.hspedu.newData.dmsxl.设计题;

import java.util.HashMap;
import java.util.Map;

/**
 * @Author: yh
 * @description: 
 * @CreateTime: 2025-05-21 
 * @Version: 1.0
 */

public class LRUCache2 {

    class DLinkedNode{
        int key;
        int value;
        DLinkedNode next;
        DLinkedNode prev;

        public DLinkedNode(int key, int value) {
            this.key = key;
            this.value = value;
        }

        public DLinkedNode() {
        }
    }

    private int size;
    private int capacity;

    private DLinkedNode head,tail;

    private Map<Integer,DLinkedNode> cache = new HashMap<>();

    public LRUCache2(int capacity) {
        size = 0;
        this.capacity = capacity;

        head = new DLinkedNode();
        tail = new DLinkedNode();

        head.next = tail;
        tail.prev = head;
    }

    public int get(int key){

        DLinkedNode node = cache.get(key);

        if (node == null){
            return -1;
        }
        moveToHead(node);
        return node.value;
    }

    public void put(int key,int value){

        DLinkedNode node = cache.get(key);

        if (node == null){
            DLinkedNode newNode = new DLinkedNode(key,value);

            cache.put(key,newNode);
            addToHead(newNode);
            size++;
            if (size>capacity){
                DLinkedNode tail = removeTail();
                cache.remove(tail.key);
                size--;
            }
        }else{
            node.value = value;
            moveToHead(node);
        }
    }

    private void moveToHead(DLinkedNode node){
        removeNode(node);
        addToHead(node);
    }

    private void addToHead(DLinkedNode node){
        node.next = head.next;
        node.prev = head;
        head.next.prev = node;
        head.next = node;
    }

    private void removeNode(DLinkedNode node){
        node.prev.next = node.next;
        node.next.prev = node.prev;
    }

    private DLinkedNode removeTail(){
        DLinkedNode node = tail.prev;
        removeNode(node);
        return node;
    }
}
